package com.reflex.question;

import com.reflex.dao.Cat;

import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Objects;
import java.util.Properties;

/**
 * @Author: lizehui
 * @Description: 反射的机制用于解决什么问题呢
 * 我们想仅通过修改配置文件信息，就能在不改变这里代码的情况下，进行调用类中的方法调用
 * @Date: 2022/11/18/11:24
 */
public class ReflexQuestion {

    public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        //正常调用对象的方法是这样的
        Cat cat = new Cat();
        cat.hi();
        System.out.println("= = = = = = = = =");

        //但是现在有一个需求：我们想仅通过修改配置文件信息，就能在不改变这里代码的情况下，进行调用类中的方法调用
        Properties properties = new Properties();
        properties.load(new FileInputStream("src/reflex.properties"));
        String classFullPath = properties.get("classFullPath").toString();
        String methodName = properties.get("method").toString();
        System.out.println(classFullPath);
        System.out.println(methodName);
        System.out.println("= = = = = = = = =");

        //接下来是不是卡住? 你现在想要通过classFullPath字符串，获取到类的实例，然后进行方法调用
        //那接下来，我就告诉你一个能通过字符串获取类实例的办法
        //1、获取配置文件中的类
        Class cls = Class.forName(classFullPath);
        //2、强转成Cat对象，然后调用hi()方法
        Cat cat1 = (Cat) cls.newInstance();
        cat1.hi();
        System.out.println("= = = = = = = = =");

        //你虽然调用成功了，但是这并不满足我们的需求
        //因为如果我们在Cat类中，新加了一个方法，比如说叫eat()
        //你是不是需要修改这里的代码，加上一个c.eat()呢？
        //那么接下来，我们不光要获取到配置文件中的类，也要获取到配置文件中的方法
        //1、获取配置文件中的类
        Class cls1 = Class.forName(classFullPath);
        //2、拿到一个类的实例
        Object o = cls1.newInstance();
        //3、获取类中的方法
        Method method = cls1.getMethod(methodName);
        //4、这里 方法.invoke(类实例) 其实就是相当于 类实例.方法
        method.invoke(o);

        //现在我们将 reflex.properties 中的 method 变为 eat
        //我们不需要修改这里的代码，就能调用eat方法了



    }















}
